/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package View.planificacion;

import Algorithm.*;
import DAO.EnvioPedidoDAO;
import Presenter.PedidoPresenter;
import java.util.logging.Level;
import java.util.logging.Logger;
import Model.EnvioPedido;
import Model.Pedido;
import java.util.*;
import javax.swing.table.DefaultTableModel;
import Principals.Utils;
import Presenter.EnvioPedidoPresenter;
import View.components.Index;
import javax.swing.JDesktopPane;
import javax.swing.JOptionPane;

/**
 *
 * @author sebastian
 */
public class Frm_PlanificarPedidos extends javax.swing.JDesktopPane {

    private List<EnvioPedidoAlg> lstEnvioPedidos = new ArrayList<EnvioPedidoAlg>();
    boolean contadorActivo = true;
    private DefaultTableModel mdlPedidos;

    /**
     * Creates new form Frm_PlanificarPedidos
     */
    public Frm_PlanificarPedidos() {
        initComponents();
        tblDistribucionPedidos.getTableHeader().setReorderingAllowed(false);
        mdlPedidos = new DefaultTableModel();
        CalcularPedidosPendientes();
        EnvioPedidoPresenter.actualizarEnvioPedido();
    }

    public void contadorTIempo() {
        Timer tmrContador = new Timer();
        tmrContador.schedule(new TimerTask() {
            @Override
            public void run() {
                //aca se ejecuta lo que se quiere que salga cada 2 segundos
                System.out.println("hola mundo");
                if (contadorActivo) {
                    contadorTIempo();
                }
            }
        }, 2 * 1000);
    }

    public void calcularPosicion() {
        //se llama al presenter que devuelca una lista de EnvioPedido para calcular la posicion del mismo en un momento dado
        List<EnvioPedido> lstEnvioPedido = new ArrayList<EnvioPedido>();
        float distanciaRecorrida;
        int tipoVehiculo = 0;
        for (int i = 0; i < lstEnvioPedido.size(); i++) {
            distanciaRecorrida = 0;
            //MANEJAR VARIABLES DE VELOCIDAD POMEDIO ETC A NIVEL DE BASE DE DATOS
            //tipoVehiculo = lstEnvioPedido.get(i).getVehiculo().getTipoVehiculo();
            //en el caso de tratarse de una moto
            if (tipoVehiculo == 0) {
                //que devuelva la cantidad de minutos pasados y multiplicarlo por una constantes de manera que parezca que ha psado mas tiempo
                int velocidadPromedio = 60;
                distanciaRecorrida = velocidadPromedio * 30 * Utils.diffHourMinutes(lstEnvioPedido.get(i).getFechaSalida(), new Date());
            }
        }
    }

    public void CalcularPedidosPendientes() {
        int cantPedidos = PedidoPresenter.cantPedidosPendientes();
        txtCanPendientes.setText(cantPedidos + "");
        if ((cantPedidos == 0) || (tblDistribucionPedidos.getSize().getHeight() == 0)) {
            btnConfirmarEnvio.setEnabled(false);
        } else {
            btnConfirmarEnvio.setEnabled(true);
        }
    }

    public void LlenarTabla(List<Double> lstFitnessSolucion) {
        Object[] fila = new Object[4];
        String pedidos = "";
        int costoPedido = 0;
        mdlPedidos.setNumRows(0);
        mdlPedidos = (DefaultTableModel) tblDistribucionPedidos.getModel();
        List<Pedido> lstPedido = new ArrayList<Pedido>();
        for (int i = 0; i < lstEnvioPedidos.size(); i++) {
            fila[0] = lstEnvioPedidos.get(i).getVehiculo().getPlaca();
            fila[1] = lstEnvioPedidos.get(i).getVehiculo().getTipoVehiculo().getValorString();
            lstPedido = new ArrayList(lstEnvioPedidos.get(i).getPedidos());
            costoPedido = 0;
            pedidos = "";
            for (int j = 0; j < lstPedido.size(); j++) {
                pedidos = pedidos + "Pedido " + lstPedido.get(j).getIdPedido();
                if (j != lstPedido.size() - 1) {
                    pedidos = pedidos + " -/- ";
                }
                costoPedido = lstPedido.get(j).getProducto().getPrecioLista().intValue() - lstPedido.get(j).getProducto().getPrecioCosto().intValue() + costoPedido;
            }
            fila[2] = pedidos;
            //PARA LA COLUMNA 3 : COSTO, cuanto nos cuesta enviar ese pedido en ese vehiculo
            lstEnvioPedidos.get(i).setUtilidad(costoPedido - lstFitnessSolucion.get(i));
            fila[3] = costoPedido - lstFitnessSolucion.get(i);
            /*deberia tener el fitnes la cada uno de los EnvioPedido para poder determinar el costo
             ALMACENARLOS EN BASE DE DATOS!!!!!!!!!!!!!!!!!!!!!!!*/
            //PARA LA COLUMNA 4 : BENEFICIO, a cuanto se vende ese prodcuto, el margen de ganancia
            mdlPedidos.insertRow(i, fila);
//            validarGanacia(costoPedido, lstFitnessSolucion.get(i), i);
        }
        btnConfirmarEnvio.setEnabled(true);
    }

    public void validarGanacia() {
        double utilidad = 0.0;
        if (ckbSeleccionAutomatica.isSelected()) {
            for (int i = 0; i < lstEnvioPedidos.size(); i++) {
                utilidad = (Double) tblDistribucionPedidos.getValueAt(i, 3);
                //TO DO <------------------- validar si se debe comparar con 0 o con el margen de ganancia minima que debe tener un pedido
                if (utilidad>0) {
                    tblDistribucionPedidos.setValueAt(true, i, 4);
                }
            }
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        btnPlanificar = new javax.swing.JButton();
        pnlPrincipal = new javax.swing.JPanel();
        pnlDistribucionPedidos = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        tblDistribucionPedidos = new javax.swing.JTable();
        btnConfirmarEnvio = new javax.swing.JButton();
        pnlPedidosPendientes = new javax.swing.JPanel();
        lblPedidos = new javax.swing.JLabel();
        txtCanPendientes = new javax.swing.JTextField();
        lblPendientes = new javax.swing.JLabel();
        btnIniciarPlanificacion = new javax.swing.JButton();
        ckbSeleccionAutomatica = new javax.swing.JCheckBox();

        btnPlanificar.setText("Iniciar Planificacion");

        pnlDistribucionPedidos.setBorder(javax.swing.BorderFactory.createTitledBorder("Distribución de Pedidos"));

        tblDistribucionPedidos.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Vehículo", "Tipo de Vehículo", "Lista de Pedidos", "Utilidad", "Seleccione"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Float.class, java.lang.Boolean.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false, false, true
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane1.setViewportView(tblDistribucionPedidos);
        tblDistribucionPedidos.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);

        btnConfirmarEnvio.setText("Confirmar Envios");
        btnConfirmarEnvio.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConfirmarEnvioActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout pnlDistribucionPedidosLayout = new org.jdesktop.layout.GroupLayout(pnlDistribucionPedidos);
        pnlDistribucionPedidos.setLayout(pnlDistribucionPedidosLayout);
        pnlDistribucionPedidosLayout.setHorizontalGroup(
            pnlDistribucionPedidosLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(pnlDistribucionPedidosLayout.createSequentialGroup()
                .add(343, 343, 343)
                .add(btnConfirmarEnvio, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 199, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(0, 367, Short.MAX_VALUE))
            .add(pnlDistribucionPedidosLayout.createSequentialGroup()
                .addContainerGap()
                .add(jScrollPane1)
                .addContainerGap())
        );
        pnlDistribucionPedidosLayout.setVerticalGroup(
            pnlDistribucionPedidosLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(pnlDistribucionPedidosLayout.createSequentialGroup()
                .addContainerGap()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(btnConfirmarEnvio)
                .addContainerGap())
        );

        pnlPedidosPendientes.setBorder(javax.swing.BorderFactory.createTitledBorder("Pedidos Pendientes"));

        lblPedidos.setText("Actualmente hay");

        txtCanPendientes.setEditable(false);

        lblPendientes.setText("pedidos pendientes");

        btnIniciarPlanificacion.setText("Iniciar Planificación");
        btnIniciarPlanificacion.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnIniciarPlanificacionActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout pnlPedidosPendientesLayout = new org.jdesktop.layout.GroupLayout(pnlPedidosPendientes);
        pnlPedidosPendientes.setLayout(pnlPedidosPendientesLayout);
        pnlPedidosPendientesLayout.setHorizontalGroup(
            pnlPedidosPendientesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(pnlPedidosPendientesLayout.createSequentialGroup()
                .add(pnlPedidosPendientesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(pnlPedidosPendientesLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(lblPedidos)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(txtCanPendientes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 46, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(lblPendientes))
                    .add(pnlPedidosPendientesLayout.createSequentialGroup()
                        .add(66, 66, 66)
                        .add(btnIniciarPlanificacion, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 164, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        pnlPedidosPendientesLayout.setVerticalGroup(
            pnlPedidosPendientesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(pnlPedidosPendientesLayout.createSequentialGroup()
                .addContainerGap()
                .add(pnlPedidosPendientesLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(lblPedidos)
                    .add(txtCanPendientes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(lblPendientes))
                .add(18, 18, 18)
                .add(btnIniciarPlanificacion, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 38, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(16, Short.MAX_VALUE))
        );

        ckbSeleccionAutomatica.setSelected(true);
        ckbSeleccionAutomatica.setText("Seleccionar Automaticamente Ganancias");

        org.jdesktop.layout.GroupLayout pnlPrincipalLayout = new org.jdesktop.layout.GroupLayout(pnlPrincipal);
        pnlPrincipal.setLayout(pnlPrincipalLayout);
        pnlPrincipalLayout.setHorizontalGroup(
            pnlPrincipalLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(pnlPrincipalLayout.createSequentialGroup()
                .addContainerGap()
                .add(pnlPrincipalLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(pnlPrincipalLayout.createSequentialGroup()
                        .add(pnlDistribucionPedidos, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addContainerGap())
                    .add(pnlPrincipalLayout.createSequentialGroup()
                        .add(pnlPedidosPendientes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(ckbSeleccionAutomatica)
                        .add(17, 17, 17))))
        );
        pnlPrincipalLayout.setVerticalGroup(
            pnlPrincipalLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, pnlPrincipalLayout.createSequentialGroup()
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(pnlPrincipalLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, pnlPedidosPendientes, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, ckbSeleccionAutomatica))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(pnlDistribucionPedidos, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(pnlPrincipal, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(pnlPrincipal, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    public void enviarPedidos() {
        //identificamos que envios pedidos se envian y por tanto se actualizan
        // TO DO: REVISAR modoAuto
        List<EnvioPedidoAlg> lstEnvios = new ArrayList<EnvioPedidoAlg>();
        Boolean esElegido;
        for (int i = 0; i < lstEnvioPedidos.size(); i++) {
            esElegido = (Boolean) (tblDistribucionPedidos.getValueAt(i, 4) == null || (Boolean) tblDistribucionPedidos.getValueAt(i, 4) == false ? false : true);
            if (esElegido) {
                lstEnvios.add(lstEnvioPedidos.get(i));
            }
        }
        for (int i = 0; i < lstEnvios.size(); i++) {
            EnvioPedidoPresenter.registrarEnvioPedido(lstEnvios.get(i), 1);
        }
        cambiarVista(new Frm_Mapa(lstEnvios));
    }

    private void cambiarVista(JDesktopPane panel) {
        ((Index) (this.getTopLevelAncestor())).changeDesktopPane(panel);
    }

    public int calcularDemora(EnvioPedido objEnvioPedido) {
        int demora = 0;
        int cantidadParadas = 0;
        int distancia = 0;
        List<Pedido> lstPedidos = new ArrayList(objEnvioPedido.getPedidos());
        for (int i = 0; i < lstPedidos.size(); i++) {
        }
        return demora;
    }

    private void btnIniciarPlanificacionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnIniciarPlanificacionActionPerformed
        // TODO add your handling code here:
        //se crea el objeto de Algoritmo para iniciar la planificacion
        //contadorTIempo();
        Algoritmo objAlgoritmoGenetico = new Algoritmo();
        try {
            objAlgoritmoGenetico.load();
        } catch (Exception ex) {
            Logger.getLogger(Frm_PlanificarPedidos.class.getName()).log(Level.SEVERE, null, ex);
        }
        /*
         //se hacen validaciones para ver si hay vehiculos disponibles, pedidos pendientes y empleados disponibles
         //validar si los vehiculos alcanzan para todos los pedidos.
         if (objAlgoritmoGenetico.CANTIDAD_PEDIDOS == 0) {
         JOptionPane.showMessageDialog(null, "No existen pedidos pendientes para planificar");
         } else {
         if (objAlgoritmoGenetico.verificarCapacidadVehiculos(objAlgoritmoGenetico.CANTIDAD_PEDIDOS)) {
         List<Double> lstFitnessSolucion = new ArrayList<Double>();
         //el algoritmo debe retornar una lista de vehiculo o pedidos que permita mostrar la data en la tabla
         lstEnvioPedidos = objAlgoritmoGenetico.Genetico(lstFitnessSolucion);
         LlenarTabla(lstFitnessSolucion);
         } else {
         JOptionPane.showMessageDialog(null, "No es posible planificar debido a que no hay vehiculos suficientes para los pedidos ingresados");
         }
         }*/


        if (objAlgoritmoGenetico.CANTIDAD_PEDIDOS == 0) {
            JOptionPane.showMessageDialog(null, "No existen pedidos pendientes para planificar");
        } else {
            if (objAlgoritmoGenetico.verificarCapacidadVehiculos(objAlgoritmoGenetico.CANTIDAD_PEDIDOS)) {
                List<Double> lstFitnessSolucion = new ArrayList<Double>();
                Double Mejorbeneficio = -100000.0;

                List<EnvioPedidoAlg> lstEnvioPedidoAux;
                for (int i = 0; i < 10; i++) {
                    double beneficioActual = 0;
                    lstEnvioPedidoAux = objAlgoritmoGenetico.Genetico(lstFitnessSolucion);
                    for (int j = 0; j < lstEnvioPedidoAux.size(); j++) {
                        beneficioActual = 0.0;
                        List<Pedido> lstPedidos = lstEnvioPedidoAux.get(j).getPedidos();
                        for (int k = 0; k < lstPedidos.size(); k++) {
                            beneficioActual += lstPedidos.get(k).getProducto().getPrecioLista().intValue() - lstPedidos.get(k).getProducto().getPrecioCosto().intValue() - lstFitnessSolucion.get(j);
                        }
                    }
                    if (beneficioActual > Mejorbeneficio) {
                        lstEnvioPedidos = lstEnvioPedidoAux;
                    }
                }
                LlenarTabla(lstFitnessSolucion);
                validarGanacia();
            } else {
                JOptionPane.showMessageDialog(null, "No es posible planificar debido a que no hay vehiculos suficientes para los pedidos ingresados");
            }
        }
    }//GEN-LAST:event_btnIniciarPlanificacionActionPerformed

    private void btnConfirmarEnvioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConfirmarEnvioActionPerformed
        //esto codigo cambia de estado a los pedidos seleccionados
        enviarPedidos();
    }//GEN-LAST:event_btnConfirmarEnvioActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnConfirmarEnvio;
    private javax.swing.JButton btnIniciarPlanificacion;
    private javax.swing.JButton btnPlanificar;
    private javax.swing.JCheckBox ckbSeleccionAutomatica;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblPedidos;
    private javax.swing.JLabel lblPendientes;
    private javax.swing.JPanel pnlDistribucionPedidos;
    private javax.swing.JPanel pnlPedidosPendientes;
    private javax.swing.JPanel pnlPrincipal;
    private javax.swing.JTable tblDistribucionPedidos;
    private javax.swing.JTextField txtCanPendientes;
    // End of variables declaration//GEN-END:variables
}